import * as crypto from 'node:crypto'
import * as bcrypt from 'bcryptjs'
import { BadRequestException, ParseIntPipe } from '@nestjs/common'
import * as dayjs from 'dayjs'

export function md5(str: any) {
  const hash = crypto.createHash('md5')
  hash.update(str)
  return hash.digest('hex')
}

export const BcryptPassword = {
  // 生成时，随机加盐，加盐处理，迭代哈希，最终生成的密文包含了版本信息、盐值和哈希值。
  async generate(str: any, salt = 10) {
    return await bcrypt.hash(str, salt)
  },
  // 验证时，BCrypt可以从密文中提取出盐值和哈希值，并使用相同的盐值对输入的字符串进行哈希计算
  async compare(str: any, hash: any) {
    return await bcrypt.compare(str, hash)
  },
}

export function generateParseIntPipe(name: any) {
  return new ParseIntPipe({
    exceptionFactory() {
      throw new BadRequestException(`${name} 应该传数字`)
    },
  })
}

export function formatDate(date: Date) {
  // 需要去掉尾巴，不然会相差16个小时
  const dt = date.toISOString().split('.')[0]
  return dayjs(dt).format('YYYY-MM-DD HH:mm:ss')
}

export function omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {
  return Object.keys(obj).reduce((acc, key) => {
    if (!keys.includes(key as K)) {
      acc[key] = obj[key]
    }
    return acc
  }, {} as Omit<T, K>)
}
